﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kevin.Framework.Data.OrmMapping;
using Kevin.Framework.Core;
using System.Data;
using System.Web.Script.Serialization;
using Kevin.Framework.Data;

namespace JOIN.Rights.BLL
{
    public  class BLLBase<T>: IBLL<T> where T:EntityBase
    {
        #region [ Constructor ]

        /// <summary>
        /// 传说中的构造函数
        /// </summary>
        public BLLBase()
            : this(null)
        { }

        /// <summary>
        /// 传说中的构造函数
        /// </summary>
        public BLLBase(T entity)
            : this(entity, OperState.Add)
        {

        }

        /// <summary>
        /// 传说中的构造函数
        /// </summary>
        public BLLBase(T entity, OperState operState)
        {
            this.Entity = entity;            
            this.OperState = operState;
        }

        #endregion

        #region [ Properties ]

        /// <summary>
        /// 单据号码前缀
        /// </summary>
        public string Bill_NO_Prefix
        {
            get;
            set;
        }

        /// <summary>
        /// 单据号码
        /// </summary>
        public string Bill_NO
        {
            get;
            set;
        }

        /// <summary>
        /// 单据类型说明
        /// </summary>

        protected virtual string BillTypeDescript
        {
            get;
            set;
        }


        /// <summary>
        /// 本票单据 操作类型
        /// </summary>
        public OperState OperState
        {
            get;
            set;
        }

        /// <summary>
        /// 本票单据 操作类型说明
        /// </summary>
        protected string OperStateDESC
        {
            get { return EnumDescAttribute.GetDescription(this.OperState); }
        }

        /// <summary>
        /// 单据实体
        /// </summary>
        public T Entity
        {
            set;
            get;
        }

        protected ServiceResult<T> ServiceResult = null;

        #endregion

        #region [ Protected Methods ]

        /// <summary>
        /// 保存之前的预处理，各单据如有必要请自定义方法体
        /// </summary>
        /// <returns></returns>
        protected virtual bool PreSaveProcess()
        {
            return true;
        }

        /// <summary>
        /// 保存之后的处理，已经实现一般日志记录
        /// </summary>
        protected virtual void AfterSaveProcess()
        {
            this.InsertLogs();
        }

        /// <summary>
        /// 保存[新增、更新]
        /// </summary>
        /// <param name="entity"></param>
        protected virtual ServiceResult<T> Save()
        {
            //DCIS.DbAccess.IDbAccess dbAccess = CoreConfig.ConnectionInfo.GetDBAccess();
            //dbAccess.BeginTrans();
            try
            {
                if (!this.PreSaveProcess())
                {
                    return ServiceResult;
                }
                switch (OperState)
                {
                    case OperState.Add:
                        this.Entity.Insert();
                        //IUD_Operation.Insert(this.Entity, this.Bill_NO);
                        break;
                    case OperState.Edit:
                        this.Entity.Update();
                        //IUD_Operation.Update(this.Entity, this.Bill_NO);
                        break;
                    case OperState.Del:
                        this.Entity.Delete();    
                    //this.Delete();
                        break;
                    default:
                        break;
                }

                this.AfterSaveProcess();
                return ServiceResult;
                //dbAccess.Commit();
            }
            catch (Exception ex)
            {
                //dbAccess.Rollback();
                InsertErrorLogs(ex.Message);
                ServiceResult.Successed = false;
                ServiceResult.Object = this.Entity;
                ServiceResult.ErrorMsg = "单据保存失败," + "\" 单据号码：\"" + this.Bill_NO;
                return ServiceResult;
                throw new Exception("单据保存失败," + "\" 单据号码：\"" + this.Bill_NO + ex.Message);
            }
        }

        //各单据必须自己定义单据申报操作方法
        /// <summary>
        /// 提交
        /// </summary>
        /// <param name="entity"></param>
        protected virtual ServiceResult<T> Apply()
        {
            return this.ServiceResult;
        }

        /// <summary>
        /// 只提供了最简单的当前实体的删除，若有特殊要求请重载该方法
        /// </summary>
        /// <param name="entity"></param>
        protected virtual ServiceResult<T> Delete()
        {
            if (PrevDelete())
            {
                this.Entity.Delete();
            }
            AfterDelete();
            return this.ServiceResult;
        }
        /// <summary>
        /// 在删除表头之前需要做的事情
        /// </summary>
        protected virtual bool PrevDelete()
        {
            //在删除表头之前需要做的事情，如有需要请在您的派生类中重写该方法
            return true;
        }

        /// <summary>
        /// 删除表头后需要做的事情
        /// </summary>
        protected virtual bool AfterDelete()
        {
            //譬如删除表头后需要删除明细则请在您的派生类中重写该方法
            return true;
        }
        //各单据必须自己定义单据审批操作方法
        /// <summary>
        /// 审批
        /// </summary>
        /// <param name="entity"></param>
        protected virtual ServiceResult<T> Check(bool isPass, string remark, string taskID)
        {
            return null;
        }
        protected virtual ServiceResult<T> Check(bool isPass, string remark)
        {
            return null;
        }
        protected virtual ServiceResult<T> DoCheck(bool isPass, string remark)
        {
            return null;
        }

        /// <summary>
        /// 弹出消息
        /// </summary>
        /// <param name="strMsg"></param>
        protected void ShowMessage(string strMsg)
        {
            
        }

        public bool LoadByKey()
        {
            return Entity.SelectByKeys();
        }

        public DataTable LoadByeProperties()
        {
            return Entity.SelectedByProperties();
        }
        protected T ConvertJSON2Entity(string json)
        {
            T entity = new JavaScriptSerializer().Deserialize<T>(json);

            return entity;
        }
        /// <summary>
        /// 插入待办,请在您的派生类中初始化 UserTask TaskCommand
        /// </summary>
        protected void InserUserTask()
        {

           
        }

        #region [ 审批流程处理  ]
        /*
        /// <summary>
        /// 审批流程处理 - 席吉波 2011-02-24
        /// </summary>
        protected virtual void FlowProcess(bool isPass, string Remark, string taskID)
        {
            TS_FlowBLL flow = new TS_FlowBLL(this.FlowType);
            IList<TS_FLOWEntity> FlowList = flow.FlowNodesLink;

            //如果从审批列表中进入UserTask 为空
            //start
            if (this.UserTask == null)
            {
                this.UserTask = new TU_USERTASKSEntity();
                this.UserTask.ID = System.Guid.NewGuid().ToString();
            }
            //end

            if (flow.IsAutoComplete)//自动审批则给海关和企业各发送一个通知消息
            {

                this.UserTask.SENDTIME = DateTime.Now;
                this.UserTask.TOCOMP = "2324";
                this.UserTask.SUBJECT = this.Bill_NO;
                this.UserTask.STATUS_FLAG = "V";
                this.UserTask.FLOWTYPE = this.FlowType.ToString();
                this.UserTask.TYPE = FlowList[0].NODEID;
                this.UserTask.REMARK = FlowList[0].NODENAME + ":自动审批通过";
                this.UserTask.FROMCOMP = DCIS.Web.WebUserInfo.GetCurrentUser().CompID;
                this.UserTask.FROMNAME = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;

                //如果从审批列表中进入TaskCommand 为空
                if (this.TaskCommand == null)
                {
                    this.TaskCommand = new TaskCommand();
                    this.TaskCommand.BillNO = this.Bill_NO;
                    this.TaskCommand.BillType = this.BillType;
                    this.TaskCommand.TaskType = TaskType.Msg;
                }
                this.UserTask.COMMAND = this.TaskCommand.ToJSON();
                this.UserTask.MSGONLY = ((int)this.TaskCommand.TaskType).ToString();

                this.DoCheck(true, FlowList[0].NODENAME + "：审批通过 单号：" + this.Bill_NO);

                IUD_Operation.Insert(this.UserTask);
                TU_USERTASKSEntity task = (TU_USERTASKSEntity)this.UserTask.Clone();
                task.ID = System.Guid.NewGuid().ToString();
                task.TOCOMP = DCIS.Web.WebUserInfo.GetCurrentUser().CompID;
                task.FROMCOMP = "2324";
                task.FROMNAME = "常熟海关";
                IUD_Operation.Insert(task);
            }
            else //有审批流程
            {
                CompType compType = (CompType)int.Parse(DCIS.Web.WebUserInfo.GetCurrentUser().Extends["CompType"].ToString());
                //如果是企业 根据配置的审批级数将第一级审批参数发送给海关设置为可操作状态 'A'
                if (!compType.Equals(CompType.Custom))
                {
                    //add by ywj 如果是审批不通过的单证再次申报，则不向代办表中新增记录，而是修改原来代办记录的状态  V--> A
                    if (this.UserTask.CountByPropertys() > 0)
                    {
                        this.UserTask.SENDTIME = DateTime.Now;
                        this.UserTask.STATUS_FLAG = "A";
                        this.UserTask.REMARK = FlowList[1].NODENAME + ":等待审批";
                        IUD_Operation.Update(this.UserTask, this.Bill_NO);
                    }
                    //end 
                    else
                    {
                        this.UserTask.SENDTIME = DateTime.Now;
                        this.UserTask.TOCOMP = "2324";
                        this.UserTask.SUBJECT = this.Bill_NO;
                        this.UserTask.STATUS_FLAG = "A";
                        this.UserTask.FLOWTYPE = this.FlowType.ToString();
                        this.UserTask.TYPE = FlowList[1].NODEID;
                        this.UserTask.REMARK = FlowList[1].NODENAME + ":等待审批";
                        this.UserTask.FROMCOMP = DCIS.Web.WebUserInfo.GetCurrentUser().CompID;
                        this.UserTask.FROMNAME = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;
                        this.UserTask.COMMAND = this.TaskCommand.ToJSON();
                        this.UserTask.MSGONLY = ((int)this.TaskCommand.TaskType).ToString();
                        IUD_Operation.Insert(this.UserTask, this.Bill_NO);

                    }
                }
                else
                {
                    //如果是海关 
                    //1：审批通过，则开启下一级审批流程（插入下一级审批流程），若无下一级审批流程则调用相应审批程序并给相应企业发送通知消息

                    this.UserTask = new TU_USERTASKSEntity();
                    UserTask.ID = taskID;
                    if (UserTask.SelectByPKeys())
                    {
                        flow = new TS_FlowBLL((FlowType)Enum.Parse(typeof(FlowType), UserTask.FLOWTYPE));
                        FlowList = flow.FlowNodesLink;
                    }
                    else
                    {
                        throw new Exception("无法获取海关的审批流程，请联系相关技术人员!");
                    }
                    if (isPass)
                    {
                        //if (this.UserTask != null)
                        //{

                        //if (UserTask.SelectByPKeys())
                        //{
                        foreach (TS_FLOWEntity item in FlowList)
                        {
                            if (item.NODEID == UserTask.TYPE) //处于审批的最后环节
                            {
                                if (item.ISLASTNODE == 1)
                                {
                                    //先将自己的任务处理掉

                                    this.UserTask.CHK_NOTES = Remark;
                                    this.UserTask.REMARK = item.NODENAME + ":审批通过";
                                    this.UserTask.CHKNAME = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;
                                    this.UserTask.CHKTIME = DateTime.Now;
                                    this.UserTask.STATUS_FLAG = "V";
                                    IUD_Operation.Update(this.UserTask, this.Bill_NO);

                                    TU_USERTASKSEntity task = new TU_USERTASKSEntity();
                                    task.TOCOMP = UserTask.FROMCOMP;
                                    task.REMARK = item.NODENAME + ":审批通过";
                                    task.SUBJECT = this.Bill_NO;
                                    task.SENDTIME = DateTime.Now;

                                    TaskCommand command = new TaskCommand();
                                    command.BillNO = this.Bill_NO;
                                    command.BillType = this.BillType;
                                    command.TaskType = TaskType.Msg;

                                    task.COMMAND = command.ToJSON();
                                    task.FROMNAME = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;
                                    task.FROMCOMP = DCIS.Web.WebUserInfo.GetCurrentUser().CompID;
                                    task.STATUS_FLAG = "A";
                                    task.ID = System.Guid.NewGuid().ToString();
                                    this.UserTask.MSGONLY = ((int)command.TaskType).ToString();

                                    IUD_Operation.Insert(task, this.Bill_NO);
                                    this.DoCheck(isPass, Remark);
                                }
                                else
                                {
                                    //先将自己的任务处理掉

                                    this.UserTask.CHK_NOTES = Remark;
                                    this.UserTask.STATUS_FLAG = "V";
                                    this.UserTask.REMARK = item.NODENAME + ":审批通过";
                                    this.UserTask.CHKNAME = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;
                                    this.UserTask.CHKTIME = DateTime.Now;
                                    IUD_Operation.Update(this.UserTask, this.Bill_NO);

                                    //再给下一流程发送待办任务
                                    TU_USERTASKSEntity task = new TU_USERTASKSEntity();
                                    task.TOCOMP = UserTask.TOCOMP;
                                    task.REMARK = item.NextNode.NODENAME + ":待审";
                                    task.FROMTYPE = item.ParentNode.NODEID;
                                    task.TYPE = item.NextNode.NODEID;
                                    task.TYPE_DESC = item.NextNode.NODENAME;
                                    task.SUBJECT = this.Bill_NO;
                                    task.SENDTIME = DateTime.Now;

                                    TaskCommand command = new TaskCommand();
                                    command.BillNO = this.Bill_NO;
                                    command.BillType = this.BillType;
                                    command.TaskType = TaskType.Task;

                                    task.COMMAND = command.ToJSON();
                                    task.FROMNAME = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;
                                    task.FROMCOMP = DCIS.Web.WebUserInfo.GetCurrentUser().CompID;
                                    task.STATUS_FLAG = "A";
                                    task.ID = System.Guid.NewGuid().ToString();
                                    task.FLOWTYPE = this.UserTask.FLOWTYPE;
                                    this.UserTask.MSGONLY = ((int)command.TaskType).ToString();
                                    IUD_Operation.Insert(task, this.Bill_NO);
                                }
                            }
                        }

                        //}
                        //}
                    }
                    else
                    {
                        //2：审批不通过，则直接调用相应审批程序,并给相应的企业发送通知消息
                        //先将自己的任务处理掉
                        foreach (TS_FLOWEntity item in FlowList)
                        {
                            if (item.NODEID == UserTask.TYPE) //处于审批的最后环节
                            {

                                this.UserTask.CHK_NOTES = Remark;
                                this.UserTask.REMARK = item.NODENAME + ":审批不通过";
                                this.UserTask.CHKNAME = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;
                                this.UserTask.CHKTIME = DateTime.Now;
                                this.UserTask.STATUS_FLAG = "V";
                                this.DoCheck(isPass, Remark);
                                IUD_Operation.Update(this.UserTask, this.Bill_NO);

                                TU_USERTASKSEntity task = new TU_USERTASKSEntity();
                                task.TOCOMP = UserTask.FROMCOMP;
                                task.TONAME = UserTask.FROMNAME;
                                task.REMARK = item.NODENAME + ":审批不通过";

                                TaskCommand command = new TaskCommand();
                                command.TaskType = TaskType.Msg;
                                command.BillNO = this.Bill_NO;
                                command.BillType = this.BillType;

                                task.COMMAND = command.ToJSON();

                                task.SENDTIME = DateTime.Now;
                                task.FROMNAME = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;
                                task.FROMCOMP = DCIS.Web.WebUserInfo.GetCurrentUser().CompID;
                                task.FLOWTYPE = item.FLOWTYPE;
                                this.UserTask.MSGONLY = ((int)command.TaskType).ToString();
                                IUD_Operation.Insert(task);
                            }
                        }
                    }

                }
            }
        }
        //*/
        #endregion

        #endregion

        #region [ Private Mehtods ]

        /// <summary>
        /// 插入日志记录
        /// </summary>
        private void InsertLogs()
        {
            /*
            if (this.Log == null)
                this.Log = new LogsEntityCSTG();

            if (!string.IsNullOrEmpty(this.BillTypeDescript))
                this.Log.LOG_DESC = this.OperStateDESC + this.BillTypeDescript + "：" + this.Bill_NO;
            else
                this.Log.LOG_DESC = this.OperStateDESC + "未知的单据类型" + "：" + this.Bill_NO;

            this.Log.ID = System.Guid.NewGuid().ToString();
            this.Log.LOG_ADD_DATE = DateTime.Now;
            this.Log.LOG_ADD_USER = DCIS.Web.WebUserInfo.GetCurrentUser().UserName;
            this.Log.LOG_TYPE = (int)this.OperState;
            this.Log.LOG_TYPE_DESC = EnumDescAttribute.GetDescription(OperState);
            this.Log.SUBJECT = this.Bill_NO;

            IUD_Operation.Insert(this.Log, this.Bill_NO);
            //*/
        }


        /// <summary>
        /// 插入错误日志记录
        /// </summary>
        private void InsertErrorLogs(string exMessage)
        {
            /*
            if (this.Log == null)
                this.Log = new LogsEntityCSTG();
             
            this.Log.LOG_DESC = exMessage + "：" + this.Bill_NO;

            this.Log.ID = System.Guid.NewGuid().ToString();
            this.Log.LOG_ADD_DATE = DateTime.Now;
            this.Log.LOG_ADD_USER = "SYSTEM";
            this.Log.LOG_TYPE = 404;
            this.Log.LOG_TYPE_DESC = EnumDescAttribute.GetDescription(OperState);
            this.Log.SUBJECT = this.Bill_NO;

            IUD_Operation.Insert(this.Log, this.Bill_NO);
            //*/
        }

        private void GetFlowConfig()
        {

        }

        #endregion

        #region  [ IBill 成员 ]

        ServiceResult<T> IBLL<T>.Save()
        {
            return this.Save();
        }

        ServiceResult<T> IBLL<T>.Apply()
        {
            return this.Apply();
        }

        ServiceResult<T> IBLL<T>.Delete()
        {
            return this.Delete();
        }

        ServiceResult<T> IBLL<T>.Check(bool isPass, string remark, string taskID)
        {
            return this.Check(isPass, remark, taskID);
        }

        ServiceResult<T> IBLL<T>.Excute()
        {
            ServiceResult<T> errResult = new ServiceResult<T>();
            errResult.Object = null;
            errResult.Successed = false;
            errResult.ErrorMsg = "操作失败，未知的处理命令.";
            switch (this.OperState)
            {
                case OperState.Add:
                case OperState.Edit:
                    return this.Save();
                    break;
                case OperState.Apply:
                    return this.Apply();
                    break;
                case OperState.Del:
                    return this.Delete();
                    break;
                default:
                    return errResult;
                    break;
            }
        }

        #endregion
    }
}
